# 第七模块 DRF (实战案例)
# 1. 需求
请结合上述学习的drf知识开发 简易版《抽屉新热榜》。其中包含的功能如下:
注册
输入:手机号、用户名、密码、确认密码。
登录
输入:手机号 或 用户名 + 密码 注意:登录成功后给用户返回token,后续请求需要在url中携带token(有效期2周)
我的话题
- 我的话题列表 - 创建话题 - 修改话题 - 删除话题(逻辑删除)
我的资讯
- 创建资讯(5分钟创建一个,需要根据用户限流) 问题1:5/h 2/m; 问题2:成功后,下次再创建; - 文本(你问我答、42区、挨踢1024、段子) - 图片(图片、你问我答、42区、挨踢1024、段子) - 连接(图片、你问我答、42区、挨踢1024、段子) 注意:创建时默认自己做1个推荐。 - 我的资讯列表
首页
- 资讯首页 - 时间倒序,读取已审核通过的资讯 - 加载更多,分页处理 - 支持传入参数,查询各分区资讯:图片、你问我答、42区、挨踢1024、段子 ?zone=2
推荐
- 推荐 - 取消推荐 - 我的推荐列表
收藏
- 收藏 or 取消收藏 - 我的收藏列表
评论
- 查看评论列表 - 根据【后代的更新时间】从大到小排序,读取根评论,每次读20条。 - 读取根评论先关的子评论。 - 将子评论挂靠到跟评论上,最终形成父子关系通过JSON返回给前端。 注意:自己也可以通过depth实现逐步读取子评论(此处不这样操作) - 创建评论 - 判断是根评论 or 回复 - 回复时,深度+1 - 评论后,找到根评论去更新【后代的更新时间】
# 2. 参考表结构
表结构参考:
from django.db import models
class DeletedModel(models.Model):
deleted = models.BooleanField(verbose_name="已删除", default=False)
class Meta:
abstract = True
class UserInfo(DeletedModel):
""" 用户表 """
username = models.CharField(verbose_name="用户名", max_length=32)
phone = models.CharField(verbose_name="手机号", max_length=32, db_index=True)
password = models.CharField(verbose_name="密码", max_length=64)
token = models.CharField(verbose_name="token", max_length=64, null=True, blank=True, db_index=True)
token_expiry_date = models.DateTimeField(verbose_name="token有效期", null=True, blank=True)
status_choice = (
(1, "激活"),
(2, "禁用"),
)
status = models.IntegerField(verbose_name="状态", choices=status_choice, default=1)
create_datetime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
class Meta:
# The newer indexes option provides more functionality than index_together
# index_together may be deprecated in the future.
# https://docs.djangoproject.com/en/3.2/ref/models/options/#index-together
indexes = [
models.Index(fields=['username', "password"], name='idx_name_pwd')
]
class Topic(DeletedModel):
""" 话题 """
title = models.CharField(verbose_name="话题", max_length=16, db_index=True)
is_hot = models.BooleanField(verbose_name="热门话题", default=False)
user = models.ForeignKey(verbose_name="用户", to="UserInfo", on_delete=models.CASCADE)
create_datetime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
class News(DeletedModel):
""" 新闻资讯 """
zone_choices = ((1, "42区"), (2, "段子"), (3, "图片"), (4, "挨踢1024"), (5, "你问我答"))
zone = models.IntegerField(verbose_name="专区", choices=zone_choices)
title = models.CharField(verbose_name="文字", max_length=150)
url = models.CharField(verbose_name="链接", max_length=200, null=True, blank=True)
# xxxxx?xxxxxx.png,xxxxxxxx.jeg
image = models.TextField(verbose_name="图片地址", help_text="逗号分割", null=True, blank=True)
topic = models.ForeignKey(verbose_name="话题", to="Topic", on_delete=models.CASCADE, null=True, blank=True)
user = models.ForeignKey(verbose_name="用户", to="UserInfo", on_delete=models.CASCADE)
create_datetime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
status_choice = (
(1, "待审核"),
(2, "已通过"),
(3, "未通过"),
)
status = models.IntegerField(verbose_name="状态", choices=status_choice, default=1)
collect_count = models.IntegerField(verbose_name="收藏数", default=0)
recommend_count = models.IntegerField(verbose_name="推荐数", default=0)
comment_count = models.IntegerField(verbose_name="评论数", default=0)
class Collect(models.Model):
""" 收藏 """
news = models.ForeignKey(verbose_name="资讯", to="News", on_delete=models.CASCADE)
user = models.ForeignKey(verbose_name="用户", to="UserInfo", on_delete=models.CASCADE)
create_datetime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
class Meta:
# unique_together = [['news', 'user']]
constraints = [
models.UniqueConstraint(fields=['news', 'user'], name='uni_collect_news_user')
]
class Recommend(models.Model):
""" 推荐 """
news = models.ForeignKey(verbose_name="资讯", to="News", on_delete=models.CASCADE)
user = models.ForeignKey(verbose_name="用户", to="UserInfo", on_delete=models.CASCADE)
create_datetime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
class Meta:
constraints = [
models.UniqueConstraint(fields=['news', 'user'], name='uni_recommend_news_user')
]
class Comment(models.Model):
""" 评论表 """
news = models.ForeignKey(verbose_name="资讯", to="News", on_delete=models.CASCADE)
user = models.ForeignKey(verbose_name="用户", to="UserInfo", on_delete=models.CASCADE)
content = models.CharField(verbose_name="内容", max_length=150)
depth = models.IntegerField(verbose_name="深度", default=0)
root = models.ForeignKey(verbose_name="根评论", to="Comment", related_name="descendant", on_delete=models.CASCADE,
null=True, blank=True)
reply = models.ForeignKey(verbose_name="回复", to="Comment", related_name="reply_list", on_delete=models.CASCADE,
null=True, blank=True)
create_datetime = models.DateTimeField(verbose_name="创建时间", auto_now_add=True)
# 针对根评论
descendant_update_datetime = models.DateTimeField(verbose_name="后代更新时间", auto_now_add=True)
# 3. 案例讲解
# 3.1 环境准备
基于django创建项目,例如:dig
安装必备模块
django-filter==2.4.0 django-redis==5.0.0 djangorestframework==3.12.4
创建app,例如:api
注册app
INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', 'django.contrib.contenttypes', 'django.contrib.sessions', 'django.contrib.messages', 'django.contrib.staticfiles', 'rest_framework', 'django_filters', 'api.apps.ApiConfig' ]
拷贝表结构到 models.py 并 生成数据库